﻿Imports System.Text
Imports System.Runtime.InteropServices
Imports OpenCLStudy.OpenCL

''' <summary>
''' 
''' </summary>
''' <remarks>
''' <seealso>http://memeplex.blog.shinobi.jp/opencl/</seealso>
''' </remarks>
Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            txtNormal.Clear()
            txtGPU.Clear()
            'Call Me.CalcNormal()
            Call Me.CalcGPU()
        Catch ex As Exception
            Throw
        End Try
    End Sub

    Private Sub CalcNormal()
        Dim result As Double
        Dim watch As New Stopwatch
        Try
            watch.Start()
            For idx As Double = 0 To 10000000000
                result += idx
            Next
            watch.Stop()
            With New StringBuilder
                .AppendLine(String.Format("経過時間(s)：{0}", watch.Elapsed.TotalSeconds))
                .AppendLine(String.Format("合計：{0}", result))
                txtNormal.AppendText(.ToString)
            End With
        Catch ex As Exception
            Throw
        End Try
    End Sub

    Private Sub CalcGPU()
        Dim platformCount As Integer = 0
        Dim watch As New Stopwatch
        Dim resultPlatform As New StringBuilder
        Dim resultDevice As New StringBuilder
        Dim resultProgram As New StringBuilder
        Dim watchPlatform As Double = 0
        Dim watchDevice As Double = 0
        Dim watchContext As Double = 0
        Dim watchQueue As Double = 0
        Dim watchProgram As Double = 0

        Dim platList As PlatformCollection
        Dim queueList As CommandQueueCollection
        Try
            'プラットフォーム
            watch.Start()
            platList = New PlatformCollection
            Call platList.Load() 'プラットフォーム情報読み込み
            With resultPlatform
                For Each plat As Platform In platList
                    .Append(plat.ToString)
                Next
            End With
            watch.Stop()
            watchPlatform = watch.Elapsed.TotalSeconds

            'デバイス
            watch.Reset()
            watch.Start()
            With resultDevice
                For Each platform As Platform In platList
                    platform.DeviceList.Load(platform)
                    For Each device As Device In platform.DeviceList
                        .Append(device.ToString)
                    Next
                Next
            End With
            watch.Stop()
            watchDevice = watch.Elapsed.TotalSeconds

            'デバイスID一覧
            Dim devIDList As New List(Of IntPtr)
            For Each platform As Platform In platList
                Call devIDList.AddRange(platform.DeviceList.IDList)
            Next
            'コンテキスト
            watch.Reset()
            watch.Start()
            Dim context As New Context(devIDList.ToArray)
            watch.Stop()
            watchContext = watch.Elapsed.TotalSeconds

            'コマンドキュー
            watch.Reset()
            watch.Start()
            queueList = New CommandQueueCollection
            For Each id As IntPtr In devIDList
                queueList.Load(context, id)
            Next
            watch.Stop()
            watchQueue = watch.Elapsed.TotalSeconds

            'バッファー
            watch.Reset()
            watch.Start()
            With resultProgram
                Dim program As New Program(context, System.IO.File.ReadAllText("simpleGL.cl"))
                For Each platform As Platform In platList
                    program.Build(platform.DeviceList(0).ID)
                    Dim kernel As New Kernel(program, "myKernelFunction")
                    Dim buffer__1 As Buffer = Buffer.FromCopiedHostMemory(context, New Single() {1, 2, 3})
                    kernel.SetArgument(0, buffer__1)

                    Const bufferSize As Integer = 3
                    queueList(0).EnqueueRange(kernel, New MultiDimension(bufferSize), New MultiDimension(1))

                    'queueList(0).EnqueueTask(kernel)
                    Dim readBack As Single() = New Single(2) {}
                    queueList(0).ReadBuffer(buffer__1, readBack)
                    For Each number As Single In readBack
                        .AppendLine(number)
                    Next
                Next
            End With
            watch.Stop()
            watchProgram = watch.Elapsed.TotalSeconds


            With New StringBuilder
                .AppendLine("全体")
                .AppendLine(String.Format("経過時間(s)：{0}", (watchPlatform + watchDevice + watchContext + watchQueue + watchProgram)))
                .AppendLine("")
                .AppendLine("プラットフォーム")
                .AppendLine(String.Format("経過時間(s)：{0}", watchPlatform))
                .AppendLine(resultPlatform.ToString)
                .AppendLine("デバイス")
                .AppendLine(String.Format("経過時間(s)：{0}", watchDevice))
                .AppendLine(resultDevice.ToString)
                .AppendLine("計算領域の確保（コンテキスト）")
                .AppendLine(String.Format("経過時間(s)：{0}", watchContext))
                .AppendLine("コマンドキュー")
                .AppendLine(String.Format("経過時間(s)：{0}", watchQueue))
                .AppendLine("プログラム")
                .AppendLine(String.Format("経過時間(s)：{0}", watchProgram))
                .AppendLine(resultProgram.ToString)

                txtGPU.AppendText(.ToString)
            End With
        Catch ex As Exception
            Throw
        End Try
    End Sub

End Class